package lxn;

import static org.junit.Assert.assertTrue;
import robocode.RoundEndedEvent;
import robocode.control.events.BattleCompletedEvent;
import robocode.control.events.TurnEndedEvent;
import robocode.control.snapshot.IRobotSnapshot;
import robocode.control.snapshot.RobotState;
import robocode.control.testing.RobotTestBed;

/**
 * This tests if Obon can move away from the wall after colliding into a wall.
 *
 * @author Leonardo Nguyen
 * @version Java 1.6.0_21
 */
public class TestObonMoveFromBorder extends RobotTestBed {

  private boolean hasCollidedIntoWall = false;
  private boolean hasMovedAwayFromWall = false;
  
  /**
   * Specifies that SittingDuck and Obon are to be matched up in this test case.
   * 
   * @return The comma-delimited list of robots in this match.
   */
  @Override public String getRobotNames() {
    return "sample.Tracker,lxn.Obon";
  }
  
  /**
   * At the end of each turn, check to see if Obon has collided into a wall and if Obon has
   * successfully moved away from the wall after collision.
   * 
   * @param event Info about the current state of the battle.
   */
  @Override public void onTurnEnded (TurnEndedEvent event) {
    
    IRobotSnapshot obon = event.getTurnSnapshot().getRobots()[1];
    double xPos = obon.getX();
    double yPos = obon.getY();
    RobotState robotStatus = obon.getState();

    // Track if Obon has collided into a wall.
    if (!hasCollidedIntoWall) {
      hasCollidedIntoWall = robotStatus.isHitWall();
    }
    
    // If Obon has collided into a wall and is now currently located beyond the border
    // along the wall, Obon must have been able to remove itself from the wall.
    if (hasCollidedIntoWall && !hasMovedAwayFromWall && (xPos > 50 && yPos > 50) && 
        (xPos < width - 50 && yPos > 50) && (xPos < width - 50 && yPos < height - 50) && 
        (xPos > 50 && yPos < height - 50)) {
      
      hasMovedAwayFromWall = true;
      
      // PMD complains about the possibility of combining two if statements together even if it
      // looks more messy.
      //if ((xPos > 50 && yPos > 50) && (xPos < width - 50 && yPos > 50) && 
      //    (xPos < width - 50 && yPos < height - 50) && (xPos > 50 && yPos < height - 50)) {
      
      //}
      
    }
  }
  
  /**
   * Resets the Obon's collision into a wall tracker if it has not removed itself from the wall at
   * the end of the round.
   * 
   * @param event Details about the completed round. 
   */
  public void onRoundEnded(RoundEndedEvent event) {
    
    if (hasCollidedIntoWall && !hasMovedAwayFromWall) {
      hasCollidedIntoWall = false;
    }
  }
  
  /**
   * This test runs for 50 rounds.
   * 
   * @return The number of rounds. 
   */
  @Override public int getNumRounds() {
    return 50;
  }
  
  /**
   * After running all the rounds, checks to see if Obon has removed itself from the wall after
   * colliding into a wall at least once.
   * 
   * @param event Details about the completed battle.
   */
  @Override public void onBattleCompleted(BattleCompletedEvent event) {
    
    assertTrue("Obon has collided into wall", hasCollidedIntoWall);
    assertTrue("Obon has moved away from the wall after collision", hasMovedAwayFromWall);
  }
}
